package service

import (
	"errors"
	"fmt"

	"GinAdmin/core/database"
	"GinAdmin/model"

	"gorm.io/gorm"
)

// DepartmentService 部门服务
type DepartmentService struct {
	db *gorm.DB
}

// NewDepartmentService 创建部门服务
func NewDepartmentService() *DepartmentService {
	return &DepartmentService{
		db: database.DB,
	}
}

// GetDepartmentByID 根据ID获取部门
func (s *DepartmentService) GetDepartmentByID(id uint) (*model.Department, error) {
	var department model.Department
	if err := s.db.First(&department, id).Error; err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return nil, fmt.Errorf("部门不存在")
		}
		return nil, err
	}
	return &department, nil
}

// DepartmentSearchParams 部门搜索参数
type DepartmentSearchParams struct {
	Name   string
	Status int
}

// GetDepartmentList 获取部门列表
func (s *DepartmentService) GetDepartmentList(params *model.DepartmentSearchParams) ([]*model.Department, error) {
	var departments []*model.Department
	db := s.db.Model(&model.Department{})

	if params.Name != "" {
		db = db.Where("name LIKE ?", "%"+params.Name+"%")
	}

	if params.Status > 0 {
		db = db.Where("status = ?", params.Status)
	}

	// 按照排序字段进行排序
	db = db.Order("sort ASC, id ASC")

	if err := db.Find(&departments).Error; err != nil {
		return nil, err
	}

	return departments, nil
}

// CreateDepartmentRequest 创建部门请求
type CreateDepartmentRequest struct {
	Name     string `json:"name" binding:"required"`
	ParentID uint   `json:"parent_id"`
	Sort     int    `json:"sort" binding:"required"`
	Status   int    `json:"status" binding:"required"`
	Remark   string `json:"remark"`
}

// CreateDepartment 创建部门
func (s *DepartmentService) CreateDepartment(req *model.CreateDepartmentRequest) (*model.Department, error) {
	// 检查部门名称是否已存在
	var count int64
	s.db.Model(&model.Department{}).Where("name = ?", req.Name).Count(&count)
	if count > 0 {
		return nil, fmt.Errorf("部门名称已存在")
	}

	// 如果有父部门，检查父部门是否存在
	if req.ParentID > 0 {
		var parent model.Department
		if err := s.db.First(&parent, req.ParentID).Error; err != nil {
			if errors.Is(err, gorm.ErrRecordNotFound) {
				return nil, fmt.Errorf("父部门不存在")
			}
			return nil, err
		}
	}

	department := &model.Department{
		Name:     req.Name,
		ParentID: req.ParentID,
		Sort:     req.Sort,
		Status:   req.Status,
		Remark:   req.Remark,
	}

	if err := s.db.Create(department).Error; err != nil {
		return nil, err
	}

	return department, nil
}

// UpdateDepartmentRequest 更新部门请求
type UpdateDepartmentRequest struct {
	Name     string `json:"name" binding:"required"`
	ParentID uint   `json:"parent_id"`
	Sort     int    `json:"sort" binding:"required"`
	Status   int    `json:"status" binding:"required"`
	Remark   string `json:"remark"`
}

// UpdateDepartment 更新部门
func (s *DepartmentService) UpdateDepartment(id uint, req *model.UpdateDepartmentRequest) (*model.Department, error) {
	department, err := s.GetDepartmentByID(id)
	if err != nil {
		return nil, err
	}

	// 检查部门名称是否已存在(除了本身)
	var count int64
	s.db.Model(&model.Department{}).Where("name = ? AND id != ?", req.Name, id).Count(&count)
	if count > 0 {
		return nil, fmt.Errorf("部门名称已存在")
	}

	// 检查是否将部门设置为自己的子部门，这会导致循环依赖
	if req.ParentID == id {
		return nil, fmt.Errorf("不能将部门设置为自己的子部门")
	}

	// 检查是否将部门设置为其子部门的子部门，这会导致循环依赖
	if req.ParentID > 0 {
		var childrenIDs []uint
		s.getChildrenDepartmentIDs(id, &childrenIDs)

		for _, childID := range childrenIDs {
			if childID == req.ParentID {
				return nil, fmt.Errorf("不能将部门设置为其子部门的子部门")
			}
		}

		// 检查父部门是否存在
		var parent model.Department
		if err := s.db.First(&parent, req.ParentID).Error; err != nil {
			if errors.Is(err, gorm.ErrRecordNotFound) {
				return nil, fmt.Errorf("父部门不存在")
			}
			return nil, err
		}
	}

	// 更新部门信息
	department.Name = req.Name
	department.ParentID = req.ParentID
	department.Sort = req.Sort
	department.Status = req.Status
	department.Remark = req.Remark

	if err := s.db.Save(department).Error; err != nil {
		return nil, err
	}

	return department, nil
}

// DeleteDepartment 删除部门
func (s *DepartmentService) DeleteDepartment(id uint) error {
	// 检查部门是否存在
	department, err := s.GetDepartmentByID(id)
	if err != nil {
		return err
	}

	// 检查是否有子部门
	var childCount int64
	if err := s.db.Model(&model.Department{}).Where("parent_id = ?", id).Count(&childCount).Error; err != nil {
		return err
	}
	if childCount > 0 {
		return fmt.Errorf("该部门下有子部门，不能删除")
	}

	// 检查是否有用户关联
	var userCount int64
	if err := s.db.Model(&model.User{}).Where("department_id = ?", id).Count(&userCount).Error; err != nil {
		return err
	}
	if userCount > 0 {
		return fmt.Errorf("该部门下有用户，不能删除")
	}

	// 删除部门
	if err := s.db.Delete(department).Error; err != nil {
		return err
	}

	return nil
}

// 递归获取所有子部门ID
func (s *DepartmentService) getChildrenDepartmentIDs(departmentID uint, ids *[]uint) {
	var children []model.Department
	s.db.Where("parent_id = ?", departmentID).Find(&children)

	for _, child := range children {
		*ids = append(*ids, child.ID)
		s.getChildrenDepartmentIDs(child.ID, ids)
	}
}

// TreeDepartment 树形部门结构
type TreeDepartment struct {
	model.Department
	Children []*TreeDepartment `json:"children"`
}

// GetDepartmentTree 获取部门树
func (s *DepartmentService) GetDepartmentTree() ([]*TreeDepartment, error) {
	var departments []*model.Department
	if err := s.db.Order("sort ASC, id ASC").Find(&departments).Error; err != nil {
		return nil, err
	}

	// 转换为树形结构
	return s.buildDepartmentTree(departments, 0), nil
}

// 构建部门树
func (s *DepartmentService) buildDepartmentTree(departments []*model.Department, parentID uint) []*TreeDepartment {
	var tree []*TreeDepartment

	for _, dept := range departments {
		if dept.ParentID == parentID {
			node := &TreeDepartment{
				Department: *dept,
				Children:   s.buildDepartmentTree(departments, dept.ID),
			}
			tree = append(tree, node)
		}
	}

	return tree
}
